package com.jgc.blockingqueue;

import org.junit.Test;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

/**
 * ArrayBlockingQueue是基于数组实现的，通过初始化时设置数组长度，是一个有界队列，而且ArrayBlockingQueue和LinkedBlockingQueue不同的是，
 * ArrayBlockingQueue只有一个锁对象，而LinkedBlockingQueue是两个锁对象，一个锁对象会造成要么是生产者获得锁，要么是消费者获得锁，两者竞争锁，无法并行
 */
public class ArrayBlockingQueueTest {
    // 创建一个固定容量为10的任务队列
    private final static int QUEUE_CAPACITY = 3;
    private final static BlockingQueue<String> taskQueue = new ArrayBlockingQueue<>(QUEUE_CAPACITY);

    public static class Producer implements Runnable{
        String[] tasks = {"Task 1", "Task 2", "Task 3", "Task 4", "Task 5", "Task 6", "Task 7", "Task 8", "Task 9", "Task 10"};
        @Override
        public void run() {
            for (String task : tasks) {
                try {
                    // 将任务放入队列，如果队列已满，则阻塞等待
                    taskQueue.put(task);
                    System.out.println("Producer put task: " + task);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    System.out.println("Producer interrupted while trying to put task");
                    return;
                }
            }
            System.out.println("All tasks have been produced.");
        }
    }

    public static class Consumer implements Runnable{
        @Override
        public void run() {
            while (true) {
                try {
                    Thread.sleep(500);
                    // 从队列取出一个任务，如果队列为空，则阻塞等待
                    String task = taskQueue.take();
                    System.out.println("Consumer took task: " + task + ", processing...");
                    // 处理任务的代码...
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    System.out.println("Consumer interrupted while trying to take task");
                    return;
                }
            }
        }
    }

    @Test
    public void test01() throws InterruptedException {
        Thread producerThread = new Thread(new Producer());
        Thread consumerThread = new Thread(new Consumer());

        producerThread.start();
        consumerThread.start();

        // 确保生产者完成任务后程序才结束
        producerThread.join();
        consumerThread.join();

        // 可以根据实际情况决定是否中断消费者线程，这里假设不再需要消费新的任务
        // consumerThread.interrupt();

    }

}
